package net.dao.impl;

import java.util.List;

import net.dao.ClaseDao;
import net.model.Clase;
import net.model.Histogram;
import net.model.RubroCalidad;

import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.LogicalExpression;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository(value = "claseDao")
public class ClaseDaoImpl implements ClaseDao {

	@Autowired
	private SessionFactory sessionFactory;

	public List<Clase> getAllClase(Boolean indeterminado,
			Boolean objetoReferencia) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(
				Clase.class);
		Criterion indeterminadoCriterion = Restrictions.eq("indeterminado",
				indeterminado);
		Criterion objetoReferenciaCriterion = Restrictions.eq(
				"objetoReferencia", objetoReferencia);
		LogicalExpression andExp = Restrictions.and(indeterminadoCriterion,
				objetoReferenciaCriterion);
		criteria.add(andExp);
		return (List<Clase>) criteria.add(andExp).list();
	}

	public List<Clase> getAllClase() {
		return (List<Clase>) sessionFactory.getCurrentSession()
				.createCriteria(Clase.class).list();
	}

	public Clase getClaseByIndeterminado(Boolean indeterminado) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(
				Clase.class);
		criteria.add(Restrictions.eq("indeterminado", indeterminado));
		List<Clase> clases = (List<Clase>) criteria.list();
		if (clases != null && clases.size() > 0) {
			return (Clase) clases.get(0);
		} else {
			return null;
		}
	}

	public Clase getClaseByObjetoReferencia(Boolean objetoReferencia) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(
				Clase.class);
		criteria.add(Restrictions.eq("objetoReferencia", objetoReferencia));
		List<Clase> clases = (List<Clase>) criteria.list();
		if (clases != null && clases.size() > 0) {
			return (Clase) clases.get(0);
		} else {
			return null;
		}
	}

	public Clase getClase(String nombreClase) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(
				Clase.class);
		criteria.add(Restrictions.eq("nombre", nombreClase));
		List<Clase> clases = (List<Clase>) criteria.list();
		if (clases != null && clases.size() > 0) {
			return (Clase) clases.get(0);
		} else {
			return null;
		}
	}

	public void saveClase(Clase clase) {
		try {
			sessionFactory.getCurrentSession().saveOrUpdate(clase);
		} catch (org.hibernate.NonUniqueObjectException e) {
			reattachToHibernateSession(clase);
		}
	}

	public void reattachToHibernateSession(Clase obj) {
		if (obj != null && obj.getId() != 0) {
			if (!sessionFactory.getCurrentSession().contains(obj)) {
				Object oldObj = sessionFactory.getCurrentSession().get(
						obj.getClass(), obj.getId());
				if (oldObj != null) {
					sessionFactory.getCurrentSession().evict(oldObj);
				}
				sessionFactory.getCurrentSession().lock(obj, LockMode.NONE);
			}
		}
	}
	/**
	 * Retornan el Histograma de un dado tipo
	 * 
	 * @param tipo
	 * @return
	 */
	public Histogram getHistogram(String nombreClase, String tipo) {
		Clase clase = getClase(nombreClase);
		Histogram h = new Histogram();
		h.setTipo(tipo);
		if (clase.getHistograms() != null) {
			int index = clase.getHistograms().indexOf(h);
			if (index != -1)
				return clase.getHistograms().get(index);
		}
		return null;
	}

	public List<Histogram> getHistogram(String nombreClase) {
		Clase clase = getClase(nombreClase);
		if (clase.getHistograms() != null) {
			if (clase.getHistograms() != null)
				return clase.getHistograms();
		}
		return null;
	}

	@Override
	public RubroCalidad getRubroCalidad(String nombre) {
		Clase clase = getClase(nombre);
		if (clase.getRubroCalidad() != null) {
				return clase.getRubroCalidad();
		}
		return null;
	}

}
